#include "CAnimals.h"
#include <stdio.h>

CAnimals Animals;

// {1904BE9D-0377-453E-989A-C8BA4F3F940E}
const GUID CLSID_ANIMALS =
{ 0x1904be9d, 0x377, 0x453e, { 0x98, 0x9a, 0xc8, 0xba, 0x4f, 0x3f, 0x94, 0xe } };

CAnimals::CAnimals() : m_nCnt(0)
{
}

CAnimals::~CAnimals()
{
}

HRESULT __stdcall CAnimals::QueryInterface(REFIID riid, void** ppvObject)
{
    if (!ppvObject)
        return E_POINTER;

    if (IID_IDog == riid)
    {
        AddRef();
        *ppvObject = dynamic_cast<IDog*>(this);
    }
    else if (IID_ICat == riid)
    {
        AddRef();
        *ppvObject = dynamic_cast<ICat*>(this);
    }
    else if (IID_IPig == riid)
    {
        AddRef();
        *ppvObject = dynamic_cast<IPig*>(this);
    }
    else
    {
        return E_NOINTERFACE;
    }

    if (*ppvObject == nullptr)
        return S_FALSE;

    return S_OK;
}

ULONG __stdcall CAnimals::AddRef()
{
    InterlockedIncrement(&m_nCnt);
    return m_nCnt;
}

ULONG __stdcall CAnimals::Release()
{
    if (m_nCnt > 0)
        InterlockedDecrement(&m_nCnt);
    return m_nCnt;
}

HRESULT __stdcall CAnimals::Woof(IN const unsigned char* lpString)
{
    if (lpString)
    {
        printf("Dog: ");
        printf((char*)lpString);
    }
    return S_OK;
}

HRESULT __stdcall CAnimals::Meow(IN const unsigned char* lpString)
{
    if (lpString)
    {
        printf("Cat: ");
        printf((char*)lpString);
    }
    return S_OK;
}

HRESULT __stdcall CAnimals::Oink(IN const unsigned char* lpString)
{
    if (lpString)
    {
        printf("Pig: ");
        printf((char*)lpString);
    }
    return S_OK;
}

HRESULT GetComObject(CLSID clsid, IID iid, void** ppvod)
{
    if (clsid == CLSID_ANIMALS)
    {
        return Animals.QueryInterface(iid, ppvod);
    }
    else
    {
        return S_FALSE;
    }
}

